/*
 * @Author: wuqingchun
 * @Date: 2024-04-25 09:06:41
 * @Description: 性能相关测试程序入口
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-04-26 11:26:35
 */
#include <iostream>
#include <thread>
#include <vector>

#include "perf_time.h"
#include "perf_cpu_cache.h"
#include "perf_lock.h"
#include "perf_atomic.h"



class PerfTestTool
{
public:
    static void test_cpu_cache(int argc, char** argv)
    {
        std::cout << "test_cpu_cache:" << std::endl;

        int iCount = 2;

        int iMode = 0;


        if (argc > 1)
        {
            iMode = atoi(argv[1]);
        }

        if (argc > 2)
        {
            iCount = atoi(argv[2]);
        }

        switch(iMode)
        {
            case 0:
            {
                std::cout << "CheckCacheLineSize" << std::endl;
                PerfCPUCache::CheckCacheLineSize(iCount);
                break;
            }
            case 1:
            {
                std::cout << "TestFalseSharing<Point>" << std::endl;
                PerfCPUCache::TestFalseSharing<Point>();
                break;
            }
            case 2:
            {
                std::cout << "TestFalseSharing<PointPadding>" << std::endl;
                PerfCPUCache::TestFalseSharing<PointPadding>();
                break;
            }
            case 3:
            {
                std::cout << "rowTraversal" << std::endl;
                PerfCPUCache::rowTraversal();
                break;
            }
            case 4:
            {
                std::cout << "ColumnTraversal" << std::endl;
                PerfCPUCache::ColumnTraversal();
                break;
            }
            case 5:
            {
                std::cout << "UpdateCounter" << std::endl;
                PerfCPUCache::UpdateCounter();
                break;
            }
            case 6:
            {
                std::cout << "InstructionParallelism" << std::endl;
                PerfCPUCache::InstructionParallelism();
                break;
            }
            case 7:
            {
                std::cout << "InstructionParallelism2" << std::endl;
                PerfCPUCache::InstructionParallelism2();
                break;
            }
            default:
            {
                break;
            }
        }
    }

    static void test_lock(int argc, char** argv)
    {
        LockPerfTestApp objApp;

        uint32_t uiCount = 2;
        uint32_t uiTime = 10;

        if (argc > 1)
        {
            uiCount = atoi(argv[1]);
        }

        if (argc > 2)
        {
            uiTime = atoi(argv[2]);
        }

        std::string strLockType = "atomic mutex";
        objApp.Start(uiCount, strLockType);
        sleep(uiTime);
        objApp.Stop();

        strLockType = "cpp mutex";
        objApp.Start(uiCount, strLockType);
        sleep(uiTime);
        objApp.Stop();

        strLockType = "pthread mutex";
        objApp.Start(uiCount, strLockType);
        sleep(uiTime);
        objApp.Stop();
    }

    static void test_atomic(int argc, char** argv)
    {
        PerfAtomic objAtom;

        std::cout << "\ncase >> test_atomic" << std::endl;

        uint32_t uiCount = 2;
        uint32_t uiTime = 10;

        if (argc > 1)
        {
            uiCount = atoi(argv[1]);
        }

        if (argc > 2)
        {
            uiTime = atoi(argv[2]);
        }

        objAtom.Start(uiCount, uiTime, std::memory_order::memory_order_relaxed);
        objAtom.Start(uiCount, uiTime, std::memory_order::memory_order_seq_cst);
    }
};

int main(int argc, char** argv)
{
    PerfTestTool::test_cpu_cache(argc, argv);

    //PerfTestTool::test_lock(argc, argv);
    //PerfTestTool::test_atomic(argc, argv);

    return 0;
}
